import tkinter as tk
from tkinter import filedialog, messagebox
from datetime import datetime
from PIL import Image, ImageTk
from tkcalendar import DateEntry
import json
import os

# 数据存储路径
DATA_FILE = "tasks.json"

def save_data(tasks):
    try:
        with open(DATA_FILE, 'w') as file:
            json.dump(tasks, file)
    except Exception as e:
        messagebox.showerror("Error saving data", str(e))

def load_data():
    try:
        if os.path.exists(DATA_FILE):
            with open(DATA_FILE, 'r') as file:
                return json.load(file)
        else:
            return []
    except Exception as e:
        messagebox.showerror("Error loading data", str(e))
        return []

window = tk.Tk()
window.title("To Do List")
window.geometry("800x600")

columns = ["To_Do", "In Progress", "Done"]
frames = {}
for col in columns:
    frame = tk.Canvas(window, bg='lightblue', relief=tk.RAISED, borderwidth=1)
    frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
    frames[col] = frame

def add_task(task_name, priority, due_date, image_path, dialog):
    try:
        if not task_name or not priority or not due_date:
            raise ValueError("you must enter all")
        create_window(frames["To_Do"], task_name, priority, due_date, image_path)
        dialog.destroy()
    except ValueError as ve:
        messagebox.showerror("error", str(ve))
    except Exception as e:
        messagebox.showerror("unknown error", str(e))
        dialog.destroy()

def create_window(frame, task_name, priority, due_date, image_path):
    card = frame.create_window(10, 10, anchor='nw', 
                               text=f"Task: {task_name}\nPriority: {priority}\nDue Date: {due_date}", 
                               font=('Arial', 12))
    if image_path:
        try:
            img = Image.open(image_path)
            img = img.resize((100, 100))
            img = ImageTk.PhotoImage(img)
            frame.create_image(20, 20, anchor='nw', image=img)
        except Exception as e:
            messagebox.showerror("Error loading image", str(e))

def create_card_dialog():
    dialog = tk.Toplevel(window)
    dialog.title("Create New Task")
    dialog.geometry("400x300")

    canvas_frame = tk.Canvas(dialog, bg='lightblue', width=300, height=200)
    canvas_frame.pack()

    def on_start_drag(event):
        card_id = event.widget.cget('id')
        initial_x = event.x
        initial_y = event.y
        event.widget.tag_raise(card_id)
        return "break"

    def on_motion(event):
        card_id = event.widget.cget('id')
        new_x = event.x
        new_y = event.y
        event.widget.coords(card_id, initial_x, initial_y, initial_x+150, initial_y+50)
        return "continue"

    def on_drop(event):
        card_id = event.widget.cget('id')
        frame_name = event.widget.winfo_name()
        frames[frame_name].addtag(card_id, 'withtag', 'all')
        frames[frame_name].delete(card_id)
        new_frame = frames[frame_name]
        new_frame.create_window(10, 10, anchor='nw', 
                                id=card_id, 
                                text=f"Task: {event.widget.cget('text').split(': ')[1]}\nPriority: {event.widget.cget('text').split(': ')[3]}\nDue Date: {event.widget.cget('text').split(': ')[5]}", 
                                font=('Arial', 12))
        if 'image' in event.widget.cget('tag'):
            new_frame.create_image(20, 20, anchor='nw', image=event.widget.cget('image'))
        return "break"

    task_name_var = tk.StringVar()
    priority_var = tk.StringVar(value="High")
    due_date_var = tk.StringVar(value=datetime.now().strftime('%Y-%m-%d'))

    task_name_label = tk.Label(dialog, text="Task Name:")
    task_name_label.pack(pady=5)
    task_name_entry = tk.Entry(dialog, textvariable=task_name_var)
    task_name_entry.pack(pady=5)

    priority_label = tk.Label(dialog, text="Priority:")
    priority_label.pack(pady=5)
    priority_options = ["High", "Medium", "Low"]
    priority_menu = tk.OptionMenu(dialog, priority_var, *priority_options)
    priority_menu.pack(pady=5)

    due_date_label = tk.Label(dialog, text="Due Date (YYYY-MM-DD):")
    due_date_label.pack(pady=5)
    due_date_entry = DateEntry(dialog, textvariable=due_date_var, date_pattern='yyyy-mm-dd')
    due_date_entry.pack(pady=5)

    def select_image():
        try:
            filename = filedialog.askopenfilename(title="Select Image", filetypes=[("Image Files", "*.png;*.jpg;*.jpeg;*.gif")])
            if filename:
                image_path_var.set(filename)
        except Exception as e:
            messagebox.showerror("Image Selection Error", str(e))

    def on_confirm():
        if not task_name_var.get() or not priority_var.get() or not due_date_var.get():
            messagebox.showerror("Input Error", "All fields are required.")
            return
        task_name = task_name_var.get()
        priority = priority_var.get()
        due_date = due_date_entry.get_date().strftime('%Y-%m-%d')
        image_path = image_path_var.get()
        create_window(frames["To_Do"], task_name, priority, due_date, image_path)

    confirm_button = tk.Button(dialog, text="Confirm", command=on_confirm)
    confirm_button.pack(pady=10)
    select_image_button = tk.Button(dialog, text="Select Image", command=select_image)
    select_image_button.pack(pady=5)

    card = canvas_frame.create_window(10, 10, anchor='nw', 
                                     id='card', 
                                     text="Drag me", 
                                     font=('Arial', 12), 
                                     cursor='move')
    canvas_frame.tag_bind(card, '<Button-1>', on_start_drag)
    canvas_frame.tag_bind(card, '<B4>', on_drop)
    canvas_frame.tag_bind(card, '<B4>', on_motion)

button = tk.Button(window, text="Create", command=create_card_dialog)
button.pack()

window.mainloop()